package com.health.platform.common.core.entity;

import com.health.platform.common.utils.ThreadLocalUtil;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * <p>查询条件基类</p>
 * <p>创建日期：2021-02-23</p>
 *
 * @author zhou-qf
 */
public class BaseQueryEntity {

    private StringBuilder paramBuilder = new StringBuilder();

    /**
     * 备用字符串
     */
    private String standbyStr;

    /**
     * 统一条件拼接
     */
    private String conditionStr;

    /**
     * 区划编号
     */
    private String sgbCode;
    /**
     * 区划编号
     */
    private String sgbCodeStandby;


    /**
     * 机构等级
     */
    private String unitLevel;

    /**
     * 机构编号
     */
    private String unitCode;

    /**
     * 机构类型
     */
    private String unitType;

    /**
     * 类型
     */
    private String targetType;

    /**
     * 日期参数
     * 1 今日
     * 2 上一日
     * 3 近一周
     * 4 近一月
     * 5 上月
     * 6 本月
     * 7 近一年
     * 8 上年
     * 9 本年
     */
    private Integer dateType;

    /**
     * 自定义开始日期
     */
    private String startDate;

    /**
     * 自定义结束日期
     */
    private String endDate;

    /**
     * 关键日期 现有需求是页面上的一些数据是昨日数据，或者近7日数据
     * 但是这个昨日和近7日数据，是跟页面上的日期查询条件相关联的
     * 比如说日期查询条件选择的是昨天，那么这个数据实际查的就是昨天的昨天数据^_^
     * 所以不能直接使用sysdate去查询数据，需要把这个sysdate替换成当前这个关键日期
     */
    private Date keyDate;

    public String getConditionStr() {
        if(!StringUtils.hasText(this.sgbCode)){
            // 如果前端页面没有给传递区划编号，那么就查询当前登录人所在区划下的所有区划
            String sgbCode = ThreadLocalUtil.get().getBody().getAreainfo().getCode();
            paramBuilder.append(" and t.GBCODE like '" + sgbCode +"%' ");
        }
        return paramBuilder.toString();
    }

    public String getSgbCode() {
       /* if(StringUtils.hasText(sgbCode)) {
            return " and t.GBCODE like '" + sgbCode + "%' ";
        }*/
        return sgbCode;
    }

    public void setSgbCode(String sgbCode) {
        this.sgbCode = sgbCode;
        if(StringUtils.hasText(sgbCode)) {
            paramBuilder.append(" and t.GBCODE like '" + sgbCode + "%' ");
        }
    }

    public void setUnitLevel(String unitLevel) {
        this.unitLevel = unitLevel;
        if(StringUtils.hasText(unitLevel)) {
            paramBuilder.append(" and t1.unitLevel = " + unitLevel + " ");
        }
    }

    public void setUnitCode(String unitCode) {
        this.unitCode = unitCode;
        if(StringUtils.hasText(unitCode)) {
            paramBuilder.append(" and t.ORG_CODE = " + unitCode + " ");
        }
    }

    /**
     * 设置日期参数
     * 1 今日
     * 2 上一日
     * 3 近一周
     * 4 近一月
     * 5 上月
     * 6 本月
     * 7 近一年
     * 8 上年
     * 9 本年
     */
    public void setDateType(Integer dateType) {
        this.dateType = dateType;
        if(dateType > 0){
            this.keyDate = new Date();
        }
        if(1 == dateType){
            paramBuilder.append(" and to_date(to_char(t.bus_date, 'yyyy/mm/dd'), 'yyyy/mm/dd') = to_date(to_char(sysdate, 'yyyy/mm/dd'), 'yyyy/mm/dd') ");
        } else if(2 == dateType){
            Calendar calendar=Calendar.getInstance();
            calendar.set(Calendar.HOUR_OF_DAY,-24);
            this.keyDate = calendar.getTime();
            paramBuilder.append(" and to_date(to_char(t.bus_date, 'yyyy/mm/dd'), 'yyyy/mm/dd') = to_date(to_char(sysdate-1, 'yyyy/mm/dd'), 'yyyy/mm/dd') ");
        } else if(3 == dateType){
            paramBuilder.append(" and t.bus_date >= to_date(to_char(sysdate-6, 'yyyy/mm/dd'), 'yyyy/mm/dd') ");
        } else if(4 == dateType){
            paramBuilder.append(" and t.bus_date >= add_months(trunc(sysdate,'mm'),-1) ");
        } else if(5 == dateType){
            Calendar calendar = Calendar.getInstance();
            int month = calendar.get(Calendar.MONTH);
            calendar.set(Calendar.MONTH, month-1);
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            this.keyDate = calendar.getTime();
            paramBuilder.append(" and t.bus_date >= to_date(TO_CHAR(LAST_DAY(ADD_MONTHS(SYSDATE, -2)) + 1,'YYYY/MM/DD'), 'YYYY/MM/DD')" +
                    " and t.bus_date <= to_date(TO_CHAR(LAST_DAY(ADD_MONTHS(SYSDATE, -1)),'YYYY/MM/DD'), 'YYYY/MM/DD') ");
        } else if(6 == dateType){
            paramBuilder.append(" and t.bus_date >= to_date(TO_CHAR(LAST_DAY(ADD_MONTHS(SYSDATE, -1)) + 1,'YYYY/MM/DD'), 'YYYY/MM/DD') ");
        } else if(7 == dateType){
            paramBuilder.append(" and t.bus_date >= to_date(to_char(add_months(sysdate, -12),'yyyy/mm/dd'),'yyyy/mm/dd') ");
        } else if(8 == dateType){
            Calendar c = Calendar.getInstance(Locale.CHINA);
            c.add(Calendar.YEAR, -1);
            c.set(Calendar.DAY_OF_YEAR,c.getActualMaximum(Calendar.DAY_OF_YEAR));
            this.keyDate = c.getTime();
            paramBuilder.append(" and t.bus_date >= add_months(trunc(sysdate,'yyyy'),-12)" +
                    " and t.bus_date <= (trunc(sysdate,'yyyy')-1) ");
        } else if(9 == dateType){
            paramBuilder.append(" and trunc(t.bus_date,'yyyy') = trunc(sysdate,'yyyy') ");
        }
    }

    public void setStartDate(String startDate) {
        this.startDate = startDate;
        if(StringUtils.hasText(startDate)){
            paramBuilder.append(" and t.bus_date >= to_date('" + startDate + "', 'yyyy/mm/dd') ");
        }
    }

    public void setEndDate(String endDate) {
        this.endDate = endDate;
        if(StringUtils.hasText(endDate)){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            try {
                this.keyDate = sdf.parse(endDate);
            } catch (ParseException e) {

            }
            paramBuilder.append(" and t.bus_date <= to_date('" + endDate + "', 'yyyy/mm/dd') ");
        }
    }

    public void setKeyDate(Date keyDate) {
        this.keyDate = keyDate;
    }

    /**
     * 替换Key，有的表也需要查询时间段或者区划信息，但是字段不是bus_date、GBCODE。需要替换成表内的字段
     */
    public void replaceKey(String oldKey, String newKey){
        this.paramBuilder = new StringBuilder(this.paramBuilder.toString().replaceAll(oldKey, newKey));
    }



    /********************具体业务使用，非公用*********************************/

    /**
     * 是否查询去年同期数据(注：首页均次费用使用)
     */
    private String isLastYear;

    /**
     * 血液类型(全血类,血小板类等 卫生应急使用)
     */
    private String bloodType;

    /**
     * 血型(A,B,O,AB 卫生应急使用)
     */
    private String bloodGroup;

    /**
     * 物资类型(卫生应急使用)
     */
    private String materialType;

    /**
     * 流向图截取角标
     */
    private Integer substrIndex;

    public String getUnitLevel() {
        return unitLevel;
    }

    public String getUnitCode() {
        return unitCode;
    }

    public String getTargetType() {
        return targetType;
    }

    public void setTargetType(String targetType) {
        this.targetType = targetType;
    }

    public String getIsLastYear() {
        return isLastYear;
    }

    public void setIsLastYear(String isLastYear) {
        this.isLastYear = isLastYear;
    }

    public String getBloodType() {
        return bloodType;
    }

    public void setBloodType(String bloodType) {
        this.bloodType = bloodType;
    }

    public String getBloodGroup() {
        return bloodGroup;
    }

    public void setBloodGroup(String bloodGroup) {
        this.bloodGroup = bloodGroup;
    }

    public String getMaterialType() {
        return materialType;
    }

    public void setMaterialType(String materialType) {
        this.materialType = materialType;
    }

    public void setConditionStr(String conditionStr) {
        this.conditionStr = conditionStr;
    }

    public Integer getDateType() {
        return dateType;
    }

    public String getStartDate() {
        return startDate;
    }

    public String getEndDate() {
        return endDate;
    }

    public Date getKeyDate() {
        return keyDate;
    }

    public Integer getSubstrIndex() {
        return substrIndex;
    }

    public void setSubstrIndex(Integer substrIndex) {
        this.substrIndex = substrIndex;
    }

    public String getUnitType() {
        return unitType;
    }

    public void setUnitType(String unitType) {
        this.unitType = unitType;
    }

    /**
     * 获取本周一日期
     * @return 周一日期
     */
    private static String getWeekStartDay(){
        Calendar cal = Calendar.getInstance();
        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        SimpleDateFormat sFormat = new SimpleDateFormat("yyyy/MM/dd");
        return sFormat.format(cal.getTime());
    }

    public StringBuilder getParamBuilder() {
        return paramBuilder;
    }

    public void setParamBuilder(StringBuilder paramBuilder) {
        this.paramBuilder = paramBuilder;
    }

    public String getStandbyStr() {
        return standbyStr;
    }

    public void setStandbyStr(String standbyStr) {
        this.standbyStr = standbyStr;
    }

    public String getSgbCodeStandby() {
        return sgbCodeStandby;
    }

    public void setSgbCodeStandby(String sgbCodeStandby) {
        this.sgbCodeStandby = sgbCodeStandby;
    }


}
